<?php
/**
 * Created by PhpStorm.
 * User: Ricky
 * Date: 16/12/26
 * Time: 下午8:46
 */

namespace App\Util;


/**
 * Class StringUtil
 *
 * @package App\Util
 */
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class StringUtil
{
    const MAX_STR_LEN = 1000000;//最大字串长度
    const MAX_INT = 2147483647;//最大整数
    const MIN_INT = -2147483648;//最小整数
    const HexString = 1;    //0-9 a-f A-F
    const LowHexString = 2;
    const UpperHexString = 3;
    const DigistString = 4;
    const AlphaString = 5;// a-z A-Z
    const ALnumString = 6;//a-z A-Z 0-9
    const UinString = 7;// a-z A-Z 0-9 _ 用户ID
    const EmailString = 8;///^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/ email
    const MobileString = 9;///^0?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/ mobile
    const TelString = 10;// /^([0-9]{3,4}-)?[0-9]{7,8}$/ telephone

    public static function isStrValid($str, $type)
    {
        $ret = false;
        switch ($type) {
            case self::HexString:
                $ret = preg_match('/^[0-9a-fA-F]*$/', $str);
                break;
            case self::LowHexString:
                $ret = preg_match('/^[0-9a-f]*$/', $str);
                break;
            case self::UpperHexString:
                $ret = preg_match('/^[0-9A-F]*$/', $str);
                break;
            case self::DigistString:
                $ret = preg_match('/^[0-9]*$/', $str);
                break;
            case self::AlphaString:
                $ret = preg_match('/^[a-zA-Z]*$/', $str);
                break;
            case self::ALnumString:
                $ret = preg_match('/^[a-zA-Z0-9]*$/', $str);
                break;
            case self::UinString:
                $ret = preg_match('/^[a-zA-Z0-9][a-zA-Z0-9_]*$/', $str);
                break;
            case self::EmailString:
                $ret = preg_match(
                    '/^(\w)+(\.\w+)*(\-\w+)*@(\w)+((\.\w+)+)$/', $str
                );
                break;
            case self::MobileString:
                $ret = preg_match(
                    '/^0?(10[0-9]|13[0-9]|15[0-9]|17[0-9]|18[0-9]|14[0-9])[0-9]{8}$/',
                    $str
                );
                break;
            case self::TelString:
                $ret = preg_match('/^[0-9]{3,4}-[0-9]{7,8}$/', $str);
                break;
            default:
                return false;
        }

        return $ret;

    }


    /**
     * 是否为整数,
     * 32位机器 支持 -2147483648 至2147483647L 整数
     * 64位机器支持 -9223372036854775807 至 9223372036854775807
     **/
    public static function isInt($str)
    {
        if (is_int($str)) {
            return true;
        }
        if (!is_string($str)) {//非字符串
            return false;
        }

        $index = 0;
        $len = strlen($str);
        $positive_flag = true;//
        if ($len > 0 && $str[0] == '-') {
            $positive_flag = false;
            $index++;
            if (!ctype_digit(substr($str, 1))) {
                return false;
            }
        } else {
            if ($len > 0 && $str[0] == '+') {
                $index++;
                if (!ctype_digit(substr($str, 1))) {
                    return false;
                }
            } else {
                if (!ctype_digit($str)) {
                    return false;
                }
            }
        }

        //去掉前导0
        while ($index < $len && $str[$index] == '0') {
            $index++;
        }
        if ($index == $len) {//全部是0
            return true;
        }

        if (PHP_INT_SIZE == 4) {
            //2147483647L
            if ($len - $index < 10) {
                return true;
            }
            if ($len - $index > 10) {
                return false;
            }

            if ($positive_flag) {
                if ($index > 0) {
                    return strcmp(substr($str, $index), '2147483647') <= 0;
                } else {
                    return strcmp($str, '2147483647') <= 0;
                }
            } else {
                if ($index > 0) {
                    return strcmp(substr($str, $index), '2147483648') <= 0;
                } else {
                    return strcmp($str, '2147483648') <= 0;
                }
            }
        }
        if (PHP_INT_SIZE == 8) {
            //9223372036854775807
            if ($len - $index < 19) {
                return true;
            }
            if ($len - $index > 19) {
                return false;
            }

            if ($positive_flag) {
                if ($index > 0) {
                    return strcmp(substr($str, $index), '9223372036854775807')
                    <= 0;
                } else {
                    return strcmp($str, '9223372036854775807') <= 0;
                }
            } else {
                if ($index > 0) {
                    return strcmp(substr($str, $index), '9223372036854775807')
                    <= 0;
                } else {
                    return strcmp($str, '9223372036854775807') <= 0;
                }
            }
        } else {
            return false;
        }
    }







    public static function dayAdd($date, $num)
    {
        return date("Y-m-d", strtotime($date) + 60 * 60 * 24 * $num);
    }

    public static function isValidDate($dateA)
    {
        if (strlen($dateA) != 10) {
            return false;
        }
        if (date("Y-m-d", strtotime($dateA)) != $dateA) {
            return false;
        }

        return true;
    }

    /*
     * 最多取$len的个字符，英文算1位宽度,汉字算2位宽度，
     * 只针对utf8
     */
    public static function cut_chinese($str, $len)
    {
        if (empty($str)) {
            return "";
        }
        $total_len = strlen($str);
        $pos = 0;
        $chinese_len = 0;
        $tmp_len = 0;
        while ($pos < $total_len && $chinese_len < $len) {
            $ch = ord($str[$pos]) & 0xFF;
            if ($ch < 128) {//一个字符
                $tmp_len = 1;
            } else {
                if ($ch < 0xE0) {//两个字
                    $tmp_len = 2;
                } else {
                    if ($ch < 0xF0) {//三个字
                        $tmp_len = 3;
                    } else {
                        if ($ch < 0xF8) {//4个字符
                            $tmp_len = 4;
                        } else {
                            if ($ch < 0xFC) {//5个字符
                                $tmp_len = 5;
                            } else {
                                if ($ch < 0xFE) {//6个字符
                                    $tmp_len = 6;
                                } else {
                                    return '';
                                }
                            }
                        }
                    }
                }
            }
            if ($tmp_len == 1) {
                if ($chinese_len + 1 <= $len) {
                    $chinese_len++;
                } else {
                    break;
                }
            } else {
                if ($chinese_len + 2 <= $len) {
                    $chinese_len += 2;
                } else {
                    break;
                }
            }
            $pos += $tmp_len;
        }

        return substr($str, 0, $pos);
    }

    public static function isValidCreditId($credit_type, $credit_id)
    {
        if ($credit_type == 1) {
            if (strlen($credit_id) != 18) {
                return false;
            }
            $sum = 0;
            $w = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
            for ($i = 0; $i < 17; $i++) {
                if ($credit_id[$i] < '0' || $credit_id[$i] > '9') {
                    return false;
                }
                $sum += (ord($credit_id[$i]) - ord('0')) * $w[$i];
            }
            $sum %= 11;
            $v = array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2);
            $check = $v[$sum];
            if ($check == 10) {
                if ($credit_id[17] != 'x' && $credit_id[17] != 'X') {
                    return false;
                }
            } else {
                if (ord($credit_id[17]) - ord('0') != $check) {
                    return false;
                }
            }
            //判断生日
            $year = (int)substr($credit_id, 6, 4);
            $mon = (int)substr($credit_id, 10, 2);
            $day = (int)substr($credit_id, 12, 2);
            if (!DateUtil::isValidDate($year, $mon, $day)) {
                return false;
            }

            return true;
        } else {
            if (empty($credit_id)) {
                return false;
            } else {
                return true;
            }
        }
    }


    public static function getMonDay($year, $mon)
    {
        if ($mon < 0 || $mon > 12) {
            return false;
        }
        $s = array(1, 3, 5, 7, 8, 10, 12);
        if (in_array($mon, $s)) {
            return 31;
        } else {
            if ($mon != 2) {
                return 30;
            }
        }
        if ($year % 400 == 0 || ($year % 100 != 0 && $year % 4 == 0)) {
            return 29;
        } else {
            return 28;
        }
    }

    public static function pic_url_encode($pic_url)
    {
        //uploaded/credit_id/image/日期_md5.xxx
        //格式为日期_md5
        if (empty($pic_url)) {
            return '';
        }
        if ($pic_url[0] == '/') {
            $arr = explode('/', $pic_url);
        } else {
            $arr = explode('\\', $pic_url);
        }

        if (count($arr) != 5) {
            //BaseError::throw_exception(OtherError::$PIC_URL_ERR);
            return '';
        }
        if ($arr[1] != 'uploaded') {
            //BaseError::throw_exception(OtherError::$PIC_URL_ERR);
            return '';
        }
        $ret = '';
        if ($arr[2] == 'credit_id') {
            $ret = '/c';
        } else {
            if ($arr[2] == 'school') {
                $ret = '/s';
            } else {
                if ($arr[2] == 'contract') {
                    $ret = '/t';
                } else {
                    if ($arr[2] == 'group') {
                        $ret = '/g';
                    } else {
                        //BaseError::throw_exception(OtherError::$PIC_URL_ERR);
                        return '';
                    }
                }
            }
        }
        if ($arr[3] != 'image') {
            //BaseError::throw_exception(OtherError::$PIC_URL_ERR);
            return '';
        }
        if (strlen($arr[4]) < 32) {
            //throw new Exception('pic url error',ERR_BAD_PARAM);
            //BaseError::throw_exception(OtherError::$PIC_URL_ERR);
            return '';
        }
        $pic_name = substr($arr[4], 0, 31);
        $pic_suffix = substr($arr[4], 31);
        if (strlen($pic_name) != 31 || $pic_name[8] != '_') {
            //BaseError::throw_exception(OtherError::$PIC_URL_ERR);
            return '';
        }
        $pic_name = substr($pic_name, 9) . substr($pic_name, 0, 8);
        $pic_name = strtr(base64_encode(hex2bin($pic_name)), '+/', '-_');

        return $ret . '/' . $pic_name . $pic_suffix;
    }


    /**
     * 在字符串的特定位置之前插入字符串
     *
     * @param $str    被插的串
     * @param $insert 要插的串
     * @param $index  插入的位置
     *
     * @return 生成的新串
     */
    public static function insert($str, $insert, $index)
    {
        if ($index < 0) {
            return false;
        }
        $sub_str1 = substr($str, 0, $index);
        $sub_str2 = substr($str, $index);

        return $sub_str1 . $insert . $sub_str2;
    }

    /**
     * 人民币数字转大写
     *
     * @param string $number        数值
     * @param string $int_unit      币种单位，默认"元"，有的需求可能为"圆"
     * @param bool   $is_round      是否对小数进行四舍五入
     * @param bool   $is_extra_zero 是否对整数部分以0结尾，小数存在的数字附加0,比如1960.30，
     *                              有的系统要求输出"壹仟玖佰陆拾元零叁角"，实际上"壹仟玖佰陆拾元叁角"也是对的
     *
     * @return string
     */
    public static function num2rmb(
        $number = 0, $int_unit = '元', $is_round = true, $is_extra_zero = false
    ) {
        //将数字切分成两段
        $parts = explode('.', floatval($number), 2);
        $int = isset($parts[0]) ? strval($parts[0]) : '0';
        $dec = isset($parts[1]) ? strval($parts[1]) : '';

        //如果小数点后多于2位，不四舍五入就直接截，否则就处理
        $dec_len = strlen($dec);
        if (isset($parts[1]) && $dec_len > 2) {
            $dec = $is_round ? substr(
                strrchr(strval(round(floatval("0." . $dec), 2)), '.'), 1
            ) : substr($parts[1], 0, 2);
        }

        //当number为0.001时，小数点后的金额为0元
        if (empty($int) && empty($dec)) {
            return '零';
        }

        //定义
        $chs = array('0', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
        $uni = array('', '拾', '佰', '仟');
        $dec_uni = array('角', '分');
        $exp = array('', '万');
        $res = '';

        // 整数部分从右向左找
        for ($i = strlen($int) - 1, $k = 0; $i >= 0; $k++) {
            $str = '';
            // 按照中文读写习惯，每4个字为一段进行转化，i一直在减
            for ($j = 0; $j < 4 && $i >= 0; $j++, $i--) {
                $u = $int{$i} > 0 ? $uni[$j] : ''; // 非0的数字后面添加单位
                $str = $chs[$int{$i}] . $u . $str;
            }
            //echo $str."|".($k - 2)."<br>";
            $str = rtrim($str, '0');// 去掉末尾的0
            $str = preg_replace("/0+/", "零", $str); // 替换多个连续的0
            if (!isset($exp[$k])) {
                $exp[$k] = $exp[$k - 2] . '亿'; // 构建单位
            }
            $u2 = $str != '' ? $exp[$k] : '';
            $res = $str . $u2 . $res;
        }

        // 如果小数部分处理完之后是00，需要处理下
        $dec = rtrim($dec, '0');

        // 小数部分从左向右找
        if (!empty($dec)) {
            $res .= $int_unit;
            // 是否要在整数部分以0结尾的数字后附加0，有的系统有这要求
            if ($is_extra_zero) {
                if (substr($int, -1) === '0') {
                    $res .= '零';
                }
            }

            for ($i = 0, $cnt = strlen($dec); $i < $cnt; $i++) {
                $u = $dec{$i} > 0 ? $dec_uni[$i] : ''; // 非0的数字后面添加单位
                $res .= $chs[$dec{$i}] . $u;
            }
            $res = rtrim($res, '0');// 去掉末尾的0
            $res = preg_replace("/0+/", "零", $res); // 替换多个连续的0
        } else {
            $res .= $int_unit . '整';
        }

        return $res;
    }

    /**
     * 判断名字是否符合规则
     */
    public static function isNameStr($name)
    {
        // FIXME 耦合性太大 后续要优化
        if (defined("NAME_MOCK")) {//测试桩
            return true;
        }
        if (!self::isUtf8($name)) {
            return false;
        }
        if (!preg_match(
            "/^[\x{4e00}-\x{9fa5}\x{3400}-\x{4dff}\x{20000}-\x{2a6df}·]+$/u",
            $name
        )
        ) {
            return false;
        }

        return true;
    }

    /**
     * 判断是否是utf8格式
     */
    public static function isUtf8($str)
    {
//		if (preg_match("/^([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){1}/",$word) == true || preg_match("/([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){1}$/",$word) == true || preg_match("/([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){2,}/",$word) == true){
//			return true;
//		}
//		return false;
        $pos = 0;
        $total_len = strlen($str);
        while ($pos < $total_len) {
            $ch = ord($str[$pos]) & 0xFF;
            if ($ch < 128) {//一个字符
                $tmp_len = 1;
            } else {
                if ($ch < 0xE0) {//两个字
                    $tmp_len = 2;
                } else {
                    if ($ch < 0xF0) {//三个字
                        $tmp_len = 3;
                    } else {
                        if ($ch < 0xF8) {//4个字符
                            $tmp_len = 4;
                        } else {
                            if ($ch < 0xFC) {//5个字符
                                $tmp_len = 5;
                            } else {
                                if ($ch < 0xFE) {//6个字符
                                    $tmp_len = 6;
                                } else {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
            $pos += $tmp_len;
        }

        return true;
    }

    /**
     * 替换字符串
     */
    public static function msubstr($str, $start, $length = '', $prefix = '*')
    {
        $strlen = mb_strlen($str);
        $pre = '';

        if ($length != '') {
            for ($i = 0; $i < $length; $i++) {
                $pre .= $prefix;
            }
            $str = mb_substr($str, 0, $start) . $pre . mb_substr(
                    $str, $start + $length
                );
        } else {
            for ($i = 0; $i < $strlen - $start; $i++) {
                $pre .= $prefix;
            }
            $str = mb_substr($str, 0, $start) . $pre;
        }

        return $str;
    }

    /**
     * 生成密码（包含大写字母，小写字母，数字，特殊字符）
     *
     * @param 生成密码长度 length，不少于6位
     */
    public static function gen_passwd($length)
    {
        if ($length < 6) {
            return false;
        }

        $temp_passwd = '';
        $gen_passwd_base = array(
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz',
            '0123456789', '~!@#$%^&*()_'
        );

        $temp_passwd .= $gen_passwd_base[0][mt_rand(0, 25)];
        $temp_passwd .= $gen_passwd_base[1][mt_rand(0, 25)];
        $temp_passwd .= $gen_passwd_base[2][mt_rand(0, 9)];
        $temp_passwd .= $gen_passwd_base[3][mt_rand(0, 11)];

        for ($i = 0; $i < ($length - 4); $i++) {
            $base_index = mt_rand(1, 24) % 4;
            switch ($base_index) {
                case 0:
                    $temp_passwd .= $gen_passwd_base[$base_index][mt_rand(
                        0, 25
                    )];
                    break;
                case 1:
                    $temp_passwd .= $gen_passwd_base[$base_index][mt_rand(
                        0, 25
                    )];
                    break;
                case 2:
                    $temp_passwd .= $gen_passwd_base[$base_index][mt_rand(
                        0, 9
                    )];
                    break;
                case 3:
                    $temp_passwd .= $gen_passwd_base[$base_index][mt_rand(
                        0, 11
                    )];
                    break;
            }
        }

        return str_shuffle($temp_passwd);
    }

    public static function gen_salt($length)
    {
        if ($length < 6) {
            return false;
        }

        $temp_passwd = '';
        $gen_passwd_base = array(
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz',
            '0123456789'
        );

        $temp_passwd .= $gen_passwd_base[0][mt_rand(0, 25)];
        $temp_passwd .= $gen_passwd_base[1][mt_rand(0, 25)];
        $temp_passwd .= $gen_passwd_base[2][mt_rand(0, 9)];
        //$temp_passwd .= $gen_passwd_base[3][mt_rand(0, 11)];

        for ($i = 0; $i < ($length - 3); $i++) {
            $base_index = mt_rand(1, 24) % 3;
            switch ($base_index) {
                case 0:
                    $temp_passwd .= $gen_passwd_base[$base_index][mt_rand(
                        0, 25
                    )];
                    break;
                case 1:
                    $temp_passwd .= $gen_passwd_base[$base_index][mt_rand(
                        0, 25
                    )];
                    break;
                case 2:
                    $temp_passwd .= $gen_passwd_base[$base_index][mt_rand(
                        0, 9
                    )];
                    break;
            }
        }

        return str_shuffle($temp_passwd);
    }

    public static function parse_time($date)
    {
        $str_date = "";
        $diff_time = self::diffSecondToNow($date);
        //1分钟内显示刚刚
        if ($diff_time <= 60) {
            $str_date = "刚刚";
        } elseif ($diff_time > 60 && $diff_time <= 3600) {
            //1小时内显示分钟
            $min = ceil($diff_time / 60);
            $str_date = $min . '分钟前';
        } else {
            $day = (int)floor(self::diffDayFromNow($date));
            //当天
            if ($day == 0) {
                $str_date = (int)floor($diff_time / 3600) . "小时前";
            } elseif ($day == -1) {
                //昨天
                $str_date = '昨天 ' . date('H:i', strtotime($date));
            } elseif (date('Y') == substr($date, 0, 4)) {
                //当年
                $str_date = date('m月d日 H:i', strtotime($date));
            } else {
                $str_date = date('Y年m月d日', strtotime($date));
            }
        }

        return $str_date;
    }

    public static function checkIdentitySex($num, $checkSex = '')
    {
        // 不是15位或不是18位都是无效身份证号
        if (strlen($num) != 15 && strlen($num) != 18) {
            return false;
        }
        // 是数值
        if (is_numeric($num)) {
            // 如果是15位身份证号
            if (strlen($num) == 15) {
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（6位）
                $dateNum = substr($num, 6, 6);
                // 性别（3位）
                $sexNum = substr($num, 12, 3);
            } else {
                // 如果是18位身份证号
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（8位）
                $dateNum = substr($num, 6, 8);
                // 性别（3位）
                $sexNum = substr($num, 14, 3);
                // 校验码（1位）
                $endNum = substr($num, 17, 1);
            }
        } else {
            // 不是数值
            if (strlen($num) == 15) {
                return false;
            } else {
                // 验证前17位为数值，且18位为字符x
                $check17 = substr($num, 0, 17);
                if (!is_numeric($check17)) {
                    return false;
                }
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（8位）
                $dateNum = substr($num, 6, 8);
                // 性别（3位）
                $sexNum = substr($num, 14, 3);
                // 校验码（1位）
                $endNum = substr($num, 17, 1);
                if ($endNum != 'x' && $endNum != 'X') {
                    return false;
                }
            }
        }

        // 性别1为男，2为女
        if ($checkSex == 1) {
            if (isset($sexNum)) {
                if (!self::checkSex($sexNum)) {
                    return false;
                }
            }
        } else {
            if ($checkSex == 2) {
                if (isset($sexNum)) {
                    if (self::checkSex($sexNum)) {
                        return false;
                    }
                }
            }
        }

        return true;
    }


    public static function checkIdentityBirth($num, $birth = '')
    {
        // 不是15位或不是18位都是无效身份证号
        if (strlen($num) != 15 && strlen($num) != 18) {
            return false;
        }
        // 是数值
        if (is_numeric($num)) {
            // 如果是15位身份证号
            if (strlen($num) == 15) {
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（6位）
                $dateNum = substr($num, 6, 6);
                // 性别（3位）
                $sexNum = substr($num, 12, 3);
            } else {
                // 如果是18位身份证号
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（8位）
                $dateNum = substr($num, 6, 8);
                // 性别（3位）
                $sexNum = substr($num, 14, 3);
                // 校验码（1位）
                $endNum = substr($num, 17, 1);
            }
        } else {
            // 不是数值
            if (strlen($num) == 15) {
                return false;
            } else {
                // 验证前17位为数值，且18位为字符x
                $check17 = substr($num, 0, 17);
                if (!is_numeric($check17)) {
                    return false;
                }
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（8位）
                $dateNum = substr($num, 6, 8);
                // 性别（3位）
                $sexNum = substr($num, 14, 3);
                // 校验码（1位）
                $endNum = substr($num, 17, 1);
                if ($endNum != 'x' && $endNum != 'X') {
                    return false;
                }
            }
        }
        if (strlen($dateNum) == 6) {
            $dateNum = '19' . $dateNum;
        }

        $dateNum = substr($dateNum, 0, 4) . '-' . substr($dateNum, 4, 2) . '-'
            . substr($dateNum, 6);
        if (!empty($birth)) {

            if ($dateNum != $birth) {
                return false;
            }
        }

        return true;
    }

    public static function getBirth($num)
    {
        // 不是15位或不是18位都是无效身份证号
        if (strlen($num) != 15 && strlen($num) != 18) {
            return false;
        }
        // 是数值
        if (is_numeric($num)) {
            // 如果是15位身份证号
            if (strlen($num) == 15) {
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（6位）
                $dateNum = substr($num, 6, 6);
                // 性别（3位）
                $sexNum = substr($num, 12, 3);
            } else {
                // 如果是18位身份证号
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（8位）
                $dateNum = substr($num, 6, 8);
                // 性别（3位）
                $sexNum = substr($num, 14, 3);
                // 校验码（1位）
                $endNum = substr($num, 17, 1);
            }
        } else {
            // 不是数值
            if (strlen($num) == 15) {
                return false;
            } else {
                // 验证前17位为数值，且18位为字符x
                $check17 = substr($num, 0, 17);
                if (!is_numeric($check17)) {
                    return false;
                }
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（8位）
                $dateNum = substr($num, 6, 8);
                // 性别（3位）
                $sexNum = substr($num, 14, 3);
                // 校验码（1位）
                $endNum = substr($num, 17, 1);
                if ($endNum != 'x' && $endNum != 'X') {
                    return false;
                }
            }
        }

        if (strlen($dateNum) == 6) {
            $dateNum = '19' . $dateNum;
        }

        return substr($dateNum, 0, 4) . '-' . substr($dateNum, 4, 2) . '-'
        . substr($dateNum, 6);
    }


    // $num为身份证号码，$checkSex：1为男，2为女，不输入为不验证
    public static function checkIdentity($num, $checkSex = '')
    {
        // 不是15位或不是18位都是无效身份证号
        if (strlen($num) != 15 && strlen($num) != 18) {
            return false;
        }
        // 是数值
        if (is_numeric($num)) {
            // 如果是15位身份证号
            if (strlen($num) == 15) {
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（6位）
                $dateNum = substr($num, 6, 6);
                // 性别（3位）
                $sexNum = substr($num, 12, 3);
            } else {
                // 如果是18位身份证号
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（8位）
                $dateNum = substr($num, 6, 8);
                // 性别（3位）
                $sexNum = substr($num, 14, 3);
                // 校验码（1位）
                $endNum = substr($num, 17, 1);
            }
        } else {
            // 不是数值
            if (strlen($num) == 15) {
                return false;
            } else {
                // 验证前17位为数值，且18位为字符x
                $check17 = substr($num, 0, 17);
                if (!is_numeric($check17)) {
                    return false;
                }
                // 省市县（6位）
                $areaNum = substr($num, 0, 6);
                // 出生年月（8位）
                $dateNum = substr($num, 6, 8);
                // 性别（3位）
                $sexNum = substr($num, 14, 3);
                // 校验码（1位）
                $endNum = substr($num, 17, 1);
                if ($endNum != 'x' && $endNum != 'X') {
                    return false;
                }
            }
        }

        if (isset($areaNum)) {
            if (!self::checkArea($areaNum)) {
                return false;
            }
        }

        if (isset($dateNum)) {
            if (!self::checkDate($dateNum)) {
                return false;
            }
        }

        // 性别1为男，2为女
        if ($checkSex == 1) {
            if (isset($sexNum)) {
                if (!self::checkSex($sexNum)) {
                    return false;
                }
            }
        } else {
            if ($checkSex == 2) {
                if (isset($sexNum)) {
                    if (self::checkSex($sexNum)) {
                        return false;
                    }
                }
            }
        }

        if (isset($endNum)) {
            if (!self::checkEnd($endNum, $num)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 用与将整数型的秒数转换成 H:i:s 的字符串
     *
     * @param $seconds int
     *
     * @return string
     */
    public static function secondsToString($seconds)
    {
        //只允许整形不包含小数位
        $seconds = intval($seconds);
        $hourUnit = 3600;
        $minuteUnit = 60;
        $secondUnit = 1;
        //算小时
        $hours = floor($seconds / $hourUnit);
        //取余数
        $hoursMod = $seconds % $hourUnit;
        //算分钟
        $minutes = floor($hoursMod / $minuteUnit);
        //取分钟的余数
        $minutesMod = $hoursMod % $minuteUnit;
        //算秒数
        $seconds = floor($minutesMod / $secondUnit);

        return str_pad($hours, 2, '0', STR_PAD_LEFT) . ':' . str_pad(
            $minutes, 2, '0', STR_PAD_LEFT
        ) . ':' . str_pad($seconds, 2, '0', STR_PAD_LEFT);
    }

    /**
     * 用与将 H:i:s 格式的时间转换成秒数
     *
     * @param $str
     *
     * @return int
     */
    public static function stringToSeconds($str)
    {
        $secondArr = array(
            3600, 60, 1
        );
        $timeArr = explode(':', $str);
        $times = 0;
        foreach ($timeArr as $key => $time) {
            $times += $secondArr[$key] * $time;
        }

        return $times;
    }

    // 验证城市
    private static function checkArea($area)
    {
        $num1 = substr($area, 0, 2);
        $num2 = substr($area, 2, 2);
        $num3 = substr($area, 4, 2);
        // 根据GB/T2260—999，省市代码11到65
        if (10 < $num1 && $num1 < 66) {
            return true;
        } else {
            return false;
        }
        //============
        // 对市 区进行验证
        //============
    }

    // 验证出生日期
    private static function checkDate($date)
    {
        if (strlen($date) == 6) {
            $date1 = substr($date, 0, 2);
            $date2 = substr($date, 2, 2);
            $date3 = substr($date, 4, 2);
            $statusY = self::checkY('19' . $date1);
        } else {
            $date1 = substr($date, 0, 4);
            $date2 = substr($date, 4, 2);
            $date3 = substr($date, 6, 2);
            $nowY = date("Y", time());
            if (1900 < $date1 && $date1 <= $nowY) {
                $statusY = self::checkY($date1);
            } else {
                return false;
            }
        }
        if (0 < $date2 && $date2 < 13) {
            if ($date2 == 2) {
                // 润年
                if ($statusY) {
                    if (0 < $date3 && $date3 <= 29) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    // 平年
                    if (0 < $date3 && $date3 <= 28) {
                        return true;
                    } else {
                        return false;
                    }
                }
            } else {
                $maxDateNum = self::getDateNum($date2);
                if (0 < $date3 && $date3 <= $maxDateNum) {
                    return true;
                } else {
                    return false;
                }
            }
        } else {
            return false;
        }
    }

    // 验证性别
    private static function checkSex($sex)
    {
        if ($sex % 2 == 0) {
            return false;
        } else {
            return true;
        }
    }

    // 验证18位身份证最后一位
    private static function checkEnd($end, $num)
    {
        $num = strtolower($num);
        $checkHou = array(1, 0, 'x', 9, 8, 7, 6, 5, 4, 3, 2);
        $checkGu = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
        $sum = 0;
        for ($i = 0; $i < 17; $i++) {
            $sum += (int)$checkGu[$i] * (int)$num[$i];
        }
        $checkHouParameter = $sum % 11;
        if ($checkHou[$checkHouParameter] != $num[17]) {
            return false;
        } else {
            return true;
        }
    }

    // 验证平年润年，参数年份,返回 true为润年  false为平年
    private static function checkY($Y)
    {
        if (getType($Y) == 'string') {
            $Y = (int)$Y;
        }
        if ($Y % 100 == 0) {
            if ($Y % 400 == 0) {
                return true;
            } else {
                return false;
            }
        } else {
            if ($Y % 4 == 0) {
                return true;
            } else {
                return false;
            }
        }
    }

    // 当月天数 参数月份（不包括2月）  返回天数
    private static function getDateNum($month)
    {
        if ($month == 1 || $month == 3 || $month == 5 || $month == 7
            || $month == 8
            || $month == 10
            || $month == 12
        ) {
            return 31;
        } else {
            if ($month == 2) {
            } else {
                return 30;
            }
        }
    }

    public static function getStrCaptcha($length)
    {
        $pool = '0123456789abcdefghijklmnopqrstuvwxyz';
        $len = strlen($pool) - 1;
        $captcha = '';
        for ($i = 0; $i < $length; $i++) {
            $num = mt_rand(0, $len);//产生一个0到$len之间的随机数
            $captcha .= $pool[$num];


        }
        return $captcha;
    }

    /**
     * 随机数字验证码
     * 
     * @param $length
     *
     * @return string
     */
    public static function getIntCaptcha($length)
    {
        $pool = '0123456789';
        $len = strlen($pool) - 1;
        $captcha = '';
        for ($i = 0; $i < $length; $i++) {
            $num = mt_rand(0, $len);//产生一个0到$len之间的随机数
            $captcha .= $pool[$num];


        }
        return $captcha;
    }

    public static function getUid($prefix = "")
    {
        $str = md5(uniqid(mt_rand(), true));
        return $prefix . $str;
    }
    public static function generateUid(){
        return date('Ymdhis') . str_pad(mt_rand(1, 999999), 6, '0', STR_PAD_LEFT);
    }
    public static function sql_dump()
    {
        \DB::listen(function ($sql) {
            $i = 0;
            $bindings = $sql->bindings;
            $rawSql = preg_replace_callback('/\?/', function ($matches) use ($bindings, &$i) {
                $item = isset($bindings[$i]) ? $bindings[$i] : $matches[0];
                $i++;
                return gettype($item) == 'string' ? "'$item'" : $item;
            }, $sql->sql);
            Log::debug("debug:sql is".json_encode($rawSql));
        });
    }
    public static function getAccount($prefix = ""){
        return $prefix.date("YmdHis",time()).self::getStrCaptcha(6);
    }
}